package com.leo.blog.login.config;


import com.leo.blog.login.SelfUserEntity;
import com.leo.blog.util.JsonUtils;
import com.leo.blog.util.ResultUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.configurationprocessor.json.JSONObject;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.StringUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Classname JWTCommonHanddler
 * @Description TODO
 * @Date 2023/1/15 12:00
 * @Created by XiongXiong
 * @Author: X.I.O
 *
 * JWT公共拦截
 */
@Slf4j
public class JWTCommonHanddler {

    /**
     * jwt 拦截
     * @param request
     * @param response
     * @param filterChain
     */
    public static void jwtTokenHanddler(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String tokenHeader = request.getHeader(JWTConfig.tokenHeader);
        if(tokenHeader==null || "".equals(tokenHeader)){
            Cookie[] cookies=request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    if("AuthToken".equals(cookie.getName())){
                        tokenHeader=cookie.getValue();
                        break;
                    }
                }
            }
        }
        if (null!=tokenHeader && tokenHeader.startsWith(JWTConfig.tokenPrefix)) {
            try {
                addUserInfoByJWT(request);
            }  catch (ExpiredJwtException e){
                log.info("Token过期");
            } catch (Exception e) {
                log.info("Token无效");
            }
        }
        filterChain.doFilter(request, response);
    }

    /**
     * 添加用户信息
     * @param request
     */
    public static void addUserInfoByJWT(HttpServletRequest request){
        String tokenHeader = request.getHeader(JWTConfig.tokenHeader);
        if(tokenHeader==null || "".equals(tokenHeader)){
            Cookie[] cookies=request.getCookies();
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    System.out.println(cookie.getName()+" "+cookie.getValue());
                    if("AuthToken".equals(cookie.getName())){
                        tokenHeader=cookie.getValue();
                        System.out.println("获取到cookie了"+tokenHeader);
                        break;
                    }
                }
            }
        }
        if (null!=tokenHeader && tokenHeader.startsWith(JWTConfig.tokenPrefix)) {
            // 截取JWT前缀
            String token = tokenHeader.replace(JWTConfig.tokenPrefix, "");
            // 解析JWT
            Claims claims = Jwts.parser()
                    .setSigningKey(JWTConfig.secret)
                    .parseClaimsJws(token)
                    .getBody();
            // 获取用户名
            String username = claims.getSubject();
            String userId = claims.getId();
            if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(userId)) {
                // 获取角色
                List<GrantedAuthority> authorities = new ArrayList<>();
                String authority = claims.get("authorities").toString();
                if (!StringUtils.isEmpty(authority)) {
                    List<Map<String, String>> authorityMap = JsonUtils.strToObj(authority,List.class);
                    for (Map<String, String> role : authorityMap) {
                        if (!StringUtils.isEmpty(role)) {
                            authorities.add(new SimpleGrantedAuthority(role.get("authority")));
                        }
                    }
                }
                //组装参数
                SelfUserEntity selfUserEntity = new SelfUserEntity();
                selfUserEntity.setUsername(claims.getSubject());
                selfUserEntity.setUserId(claims.getId());
                selfUserEntity.setAuthorities(authorities);
                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(selfUserEntity, userId, authorities);
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
        }
    }
}
